package com.decent.ejfadmin.collectcard.service.impl;

import cn.decent.component.shiro.entity.Admin;
import cn.decent.component.shiro.service.AdminService;
import cn.decent.component.shiro.vo.AdminVO;
import com.decent.ejfadmin.collectcard.dao.CollectCardDetailDao;
import com.decent.ejfadmin.collectcard.dao.CollectCardRecordDao;
import com.decent.ejfadmin.collectcard.entity.ManualClearing;
import com.decent.ejfadmin.collectcard.entity.SupplyCardQueryBean;
import com.decent.ejfadmin.collectcard.response.CollectCardDetailDto;
import com.decent.ejfadmin.collectcard.service.CollectCardDetailService;
import com.decent.ejfadmin.common.bean.*;
import com.decent.ejfadmin.common.enums.*;
import com.decent.ejfadmin.common.exception.OperateFailException;
import com.decent.ejfadmin.common.exception.SupException;
import com.decent.ejfadmin.common.util.Constants;
import com.decent.ejfadmin.config.OssConfig;
import com.decent.ejfadmin.config.PlatConfig;
import com.decent.ejfadmin.configure.service.ConfigureService;
import com.decent.ejfadmin.finance.dao.SupplyFinanceDao;
import com.decent.ejfadmin.finance.service.SupplyFinanceService;
import com.decent.ejfadmin.order.service.OrderService;
import com.decent.ejfadmin.tools.SupplyCardTools;
import com.decent.ejfadmin.user.dao.UserDao;
import com.decent.ejfadmin.utils.*;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 收卡明细
 *
 * @author weicx
 * @date 2018/07/17
 */
@Service
@Slf4j
public class CollectCardDetailServiceImpl implements CollectCardDetailService {
	private static final String TICKET_PIC_PARSING = "卡券解析超时";
	/**
	 * 支付宝转账:系统异常code
	 */
	private static final String TRANSFER_ABNORMAL = "20000";
	/**
	 * 成功
	 */
	private static final Integer SUCCESS = 200;
	/**
	 * 支付宝转账成功CODE
	 */
	private static final String TRANSFER_SUCCESS = "10000";
	/**
	 * 导出文件包含卡密信息的管理员账号
	 */
	private static final String DOWNLOAD_CARD_PWD_ADMIN = "15963597373";
	@Autowired
	private CollectCardDetailDao collectCardDetailDao;
	@Autowired
	private OrderService orderService;
	@Autowired
	private UserDao userDao;
	@Autowired
	private PlatConfig platConfig;
	@Autowired
	private AdminService adminService;
	@Autowired
	private CollectCardRecordDao collectCardRecordDao;
	@Autowired
	private SupplyFinanceDao supplyFinanceDao;
	@Autowired
	private SupplyFinanceService supplyFinanceService;
	@Autowired
	private ConfigureService configureService;
	@Autowired
	private OssConfig ossConfig;

	private static final Map<String, BigDecimal> EQUITY_CODE_MAP = new HashMap<>();

	/**
	 * 需要扣分的失败原因
	 */
	static {
		EQUITY_CODE_MAP.put("卡密类型错误", new BigDecimal(-1));
		EQUITY_CODE_MAP.put("卡密存在质量问题", new BigDecimal(-3));
		EQUITY_CODE_MAP.put("无二维码/无条形码", new BigDecimal(-1));
	}

	/**
	 * 收卡明细查询
	 *
	 * @param pageUnit    分页组件
	 * @param ids         会员id
	 * @param cardNumber  卡号
	 * @param batchId     批次号
	 * @param face        面值
	 * @param status      状态
	 * @param productType 运营商
	 * @param startTime   查询开始时间
	 * @param endTime     查询结束时间
	 * @param timeType    时间类型 0入库时间 1销卡时间
	 * @return MemberMessage
	 */
	@SuppressWarnings("JavadocReference")
	@Override
	public Page queryReceiveList(SupplyCardQueryBean supplyCardQueryBean, Page page) throws Exception {
		Admin adminUser = null;
		try {
			adminUser = adminService.getCurrentAdmin();
		} catch (Exception e) {
		}
		BigDecimal cardFace = StringUtils.isBlank(supplyCardQueryBean.getFace()) ? null
				: new BigDecimal(supplyCardQueryBean.getFace());
		SupplyCard card = new SupplyCard();
		card.setCardNumber(supplyCardQueryBean.getCardNumber());
		card.setBatchId(supplyCardQueryBean.getBatchId());
		card.setFace(cardFace);
		card.setProductType(supplyCardQueryBean.getProductType());

		int total = collectCardDetailDao.queryReceiveListCount(supplyCardQueryBean, card);
		page.setTotal(total);
		if (total == 0) {
			page.setResultList(new ArrayList<>());
			return page;
		}
		List<CollectCardDetailDto> collectCardDetailDtos = collectCardDetailDao
				.queryReceiveListPage(supplyCardQueryBean, card, page);
		Admin finalAdminUser = adminUser;
		collectCardDetailDtos.forEach(collectCardDetailDto -> {
			if (finalAdminUser != null && finalAdminUser.getSuperAdmin() != null
					&& finalAdminUser.getSuperAdmin().equals(true) && collectCardDetailDto.getStatus().equals(1)
					&& StringUtils.isNotBlank(collectCardDetailDto.getCardPwd())) {
				try {
					collectCardDetailDto.setCardPwd(StringUtils.trim(Des.reserveDecode(platConfig.getDesKey(),
							URLDecoder.decode(collectCardDetailDto.getCardPwd(), "UTF-8"))));
				} catch (UnsupportedEncodingException e) {
					log.warn("卡密[{}]解码异常[{}]", collectCardDetailDto.getCardPwd(), e.getMessage(), e);
				}
			} else {
				collectCardDetailDto.setCardPwd("");
			}
			parseCardSource(collectCardDetailDto);
			SupplyProduct product = null;
			if (collectCardDetailDto.getProductId() != null) {
				product = collectCardRecordDao.queryProductInfoById(collectCardDetailDto.getProductId());

			} else {
				String supplyArea = "全国";
				String area = supplyArea.equals(collectCardDetailDto.getSupplyArea()) ? "全国"
						: collectCardDetailDto.getArea();
				product = collectCardRecordDao.queryProductInfoByFaceAreaType(collectCardDetailDto.getFace(), area,
						collectCardDetailDto.getProductType());
			}
			if (product != null) {
				collectCardDetailDto.setCardOperatorName(product.getCardOperatorName());
				collectCardDetailDto.setProductName(product.getProductName());
			}

		});

		page.setResultList(collectCardDetailDtos);
		return page;
	}

	private void parseCardSource1(CollectCardDetailDto collectCardDetailDto) {
		if (Objects.nonNull(collectCardDetailDto.getAgentNo())
				&& Constants.EPAY.contains(collectCardDetailDto.getAgentNo())) {
			collectCardDetailDto.setOrderSource(PlatEnum.EJF.getPlatName());
		} else if (Objects.nonNull(collectCardDetailDto.getAgentNo())
				&& Constants.ESERVER.contains(collectCardDetailDto.getAgentNo())) {
			collectCardDetailDto.setOrderSource(PlatEnum.EASY_SERVER.getPlatName());
		} else if (Objects.equals(collectCardDetailDto.getStatus(), SupplyCardStatus.success.getStatus())
				&& CollectCardDetailDto.VIRTUAL.contains(collectCardDetailDto.getProductType())) {
			collectCardDetailDto.setOrderSource(PlatEnum.VIRTUAL.getPlatName());
		} else if (Objects.equals(collectCardDetailDto.getStatus(), SupplyCardStatus.success.getStatus())
				&& CollectCardDetailDto.FUELCARD.contains(collectCardDetailDto.getProductType())) {
			collectCardDetailDto.setOrderSource(PlatEnum.FUEL_CARD.getPlatName());
		} else {
			collectCardDetailDto.setOrderSource("-");
		}
	}

	private void parseCardSource(CollectCardDetailDto collectCardDetailDto) {
		if (Objects.nonNull(collectCardDetailDto.getCardSource())) {
			collectCardDetailDto.setOrderSource(PlatEnum.EJF.getPlatName());
		} else if (Objects.nonNull(collectCardDetailDto.getCardSource())
				&& Constants.ESERVER.contains(collectCardDetailDto.getCardSource())) {
			collectCardDetailDto.setOrderSource(PlatEnum.EASY_SERVER.getPlatName());
		} else if (Objects.equals(collectCardDetailDto.getStatus(), SupplyCardStatus.success.getStatus())
				&& CollectCardDetailDto.VIRTUAL.contains(collectCardDetailDto.getProductType())) {
			collectCardDetailDto.setOrderSource(PlatEnum.VIRTUAL.getPlatName());
		} else if (Objects.equals(collectCardDetailDto.getStatus(), SupplyCardStatus.success.getStatus())
				&& CollectCardDetailDto.FUELCARD.contains(collectCardDetailDto.getProductType())) {
			collectCardDetailDto.setOrderSource(PlatEnum.FUEL_CARD.getPlatName());
		} else {
			collectCardDetailDto.setOrderSource("-");
		}
		if (Objects.isNull(collectCardDetailDto.getCardSource())) {
			collectCardDetailDto.setOrderSource("-");
		} else if (collectCardDetailDto.getCardSource().equals("0")) {
			collectCardDetailDto.setOrderSource("原公众号或WEB");
		} else if (collectCardDetailDto.getCardSource().equals("1")) {
			collectCardDetailDto.setOrderSource("原接口");
		} else if (collectCardDetailDto.getCardSource().equals("3")) {
			collectCardDetailDto.setOrderSource("公众号");
		} else if (collectCardDetailDto.getCardSource().equals("4")) {
			collectCardDetailDto.setOrderSource("WEB");
		}
	}

	/**
	 * 修改收卡订单状态【三网】
	 *
	 * @param ids
	 * @param batchIds
	 * @param operate  操作类型,1:批次失败,2:卡号失败,3批次再次提交
	 * @param remark   operationType
	 * @return
	 */
	@Override
	public int setFail(String ids, String batchIds, Integer operate, String remark) {
		// 预判不符和等待慢速试充
		List<SupplyCard> cards = collectCardDetailDao.queryWrongFaceCard(ids, batchIds);
		// 3批次再次提交
		if (Objects.nonNull(operate) && OperationTypeEnum.BATCH_RESUBMIT.getStatus().equals(operate)) {
			List<String> subMitCards = new ArrayList<>();
			for (SupplyCard supplyCard : cards) {
				// 只能再次提交预判不符的三网卡
				if (!SupplyCardStatus.wrongFace.getStatus().equals(supplyCard.getStatus())
						|| supplyCard.getProductType() > 3) {
					continue;
				}
				supplyCard.setJudgeFace(supplyCard.getFace());
				supplyCard.setEndTime(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
				supplyCard.setStatus(SupplyCardStatus.preSell.getStatus());
				if (collectCardDetailDao.recommitCard(supplyCard) == 1) {
					// 修改成功的准备提交到易销卡队列
					subMitCards.add(supplyCard.getOrderId());
				}
			}
			int submitCount = submitCard(subMitCards);
			if (subMitCards.size() != 0 && submitCount == 0) {
				throw new OperateFailException("请求SUP会员系统提交到易销卡异常");
			}
			return submitCount;
		}
		// 失败
		int row = 0;
		String failReason = StringUtils.isBlank(remark) ? SupplyCardError.WRONG_UPLOAD_FACE : remark;
		for (SupplyCard card : cards) {
			int result = orderService.modifySupplyOrder(card.getOrderId(), card.getUserId(),
					SupplyCardStatus.fail.getStatus(), BigDecimal.ZERO, SupplyCardStatus.wrongFace.getStatus(),
					BigDecimal.ZERO, failReason);
			row = row + result;
			SupUser supUser = userDao.queryUserById(card.getUserId());
			if (Consts.OPEN.equals(supUser.getApiState()) && result == 1) {
				log.info("放入API异步通知队列的数据[{}]", card);
				orderAsyn(card.getOrderId());
			}
		}
		return row;
	}

	/**
	 * 收卡明细查询同步功能
	 *
	 * @param ids ID
	 * @return
	 */
	@Override
	public int synchronousCard(String ids) {
		List<SupplyCard> supplyCardList = orderService.querySynchronousCard(ids);
		int rows = 0;
		if (supplyCardList.size() < 1) {
			return rows;
		}
		for (SupplyCard supplyCard : supplyCardList) {
			StringBuilder md5 = new StringBuilder(100);
			List<NameValuePair> params = new ArrayList<>(3);
			// 易销卡账号
			String customerNo = SupplyCardTools.getSupplyConfig(supplyCard.getProductType(), "customerNo");
			params.add(new BasicNameValuePair("customerNo", customerNo));
			md5.append(customerNo);
			// 订单号
			params.add(new BasicNameValuePair("requestId", supplyCard.getOrderId()));
			md5.append("|").append(supplyCard.getOrderId()).append("#")
					.append(SupplyCardTools.getSupplyConfig(supplyCard.getProductType(), "customerKey"));
			// 签名
			params.add(new BasicNameValuePair("sign", Md5.getMd5(md5.toString(), true, "UTF-8")));
			String url = SupplyCardTools.getSupplyConfig(supplyCard.getProductType(), "supply_url");
			if (supplyCard.getProductType() > 3) {
				// 虚商，易缴费
				url += "querySupplyCard.do";
			} else {
				// 3大运营商，易销卡
				url += "query.action";
			}
			log.info("[{}]销卡查单接口URL:[{}][{}]", supplyCard.getCardNumber(), url, params);
			String result = Httpclient.post(url, params, "UTF-8", 30 * 1000, 30 * 1000);
			log.info("[{}]销卡查单接口返回值:[{}]", supplyCard.getCardNumber(), result);
			if (StringUtils.isBlank(result) || StringUtils.equals("读取超时", result)
					|| StringUtils.equals("请求异常", result)) {
				continue;
			}
			String[] resultAttr = result.split("\\|");
			if (resultAttr.length != 9 && resultAttr.length != 12) {
				log.warn("[{}] 销卡查单验证接口返回值[{}]格式异常", supplyCard, result);
				continue;
			}
			if ("SUCCESS,FAILED".contains(resultAttr[2])) {
				Integer state = StringUtils.equals("SUCCESS", resultAttr[2]) ? SupplyCardStatus.success.getStatus()
						: StringUtils.equals("FAILED", resultAttr[2]) ? SupplyCardStatus.fail.getStatus()
								: SupplyCardStatus.selling.getStatus();
				// 充值成功/失败
				if (StringUtils.equals(supplyCard.getOrderId(), resultAttr[1])
						&& (state.equals(SupplyCardStatus.success.getStatus())
								|| state.equals(SupplyCardStatus.fail.getStatus()))) {
					// 移动、联通、电信 保存成本价
					if (supplyCard.getProductType() <= Operator.TELECOM.getType()) {
						orderService.exkQueryDeal(supplyCard, resultAttr, state, supplyCard.getStatus());
						rows++;
					} else {
						if (orderService.modifySupplyOrder(supplyCard.getOrderId(), supplyCard.getUserId(), state,
								new BigDecimal(resultAttr[3]), supplyCard.getStatus(), new BigDecimal(resultAttr[7]),
								resultAttr[5]) != 1) {
							continue;
						}
						SupUser supUser = userDao.queryUserById(supplyCard.getUserId());
						if (Consts.OPEN.equals(supUser.getApiState())) {
							log.info("放入API异步通知队列的数据[{}]", supplyCard);
							orderAsyn(supplyCard.getOrderId());
						}
						rows++;
					}
				}
			}
		}
		return rows;
	}

	/**
	 * 收卡明细列表导出
	 *
	 * @param response
	 * @param writer
	 * @param supplyCardQueryBean
	 * @return MemberMessage
	 */
	@Override
	public void downLoad(HttpServletResponse response, ServletOutputStream writer,
			SupplyCardQueryBean supplyCardQueryBean) throws Exception {
		AdminVO admin = adminService.getCurrentAdmin();
		BigDecimal cardFace = StringUtils.isBlank(supplyCardQueryBean.getFace()) ? null
				: new BigDecimal(supplyCardQueryBean.getFace());
		SupplyCard card = new SupplyCard();
		card.setCardNumber(supplyCardQueryBean.getCardNumber());
		card.setBatchId(supplyCardQueryBean.getBatchId());
		card.setFace(cardFace);
		card.setStatus(supplyCardQueryBean.getStatus());
		card.setProductType(supplyCardQueryBean.getProductType());
		int total = collectCardDetailDao.queryReceiveListCount(supplyCardQueryBean, card);
		response.setHeader("Content-Disposition", "attachment;filename=" + System.currentTimeMillis() + ".csv");
		Page page = new Page();
		page.setSize(5000);
		page.setTotal(total);
		// 文件路径,为项目文件的根目录
		String filePath = System.getProperty("catalina.home") + "/logs/";
		File fileFolder = new File(filePath);
		if (!fileFolder.exists()) {
			fileFolder.mkdir();
		}
		// 文件名称
		String fileName = filePath + "downLoad" + System.currentTimeMillis();
		File file = new File(fileName + ".csv");
		// 生成的压缩文件存放路径及名称
		String zipName = filePath + "zipfile";
		File zipFile = new File(zipName + ".zip");
		BufferedWriter bw = null;
		OutputStream out = null;
		try {
			bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "GBK"), 24576);
			String header = "卡号,状态,批次号,面值,收卡时间,销卡时间,运营商,折扣,销卡面值,结算金额,地区,备注,订单来源,手机号码,订单号";
			boolean downloadCardPwd = StringUtils.equals(DOWNLOAD_CARD_PWD_ADMIN, admin.getPhoneNo());
			if (downloadCardPwd) {
				header = "卡号,卡密,状态,批次号,面值,收卡时间,销卡时间,运营商,折扣,销卡面值,结算金额,地区,备注,订单来源,手机号码,订单号";
			}
			bw.write(header);
			bw.newLine();
			while (page.getPage() <= (page.getMaxPage() + 1)) {
				List<CollectCardDetailDto> results = collectCardDetailDao.queryReceiveListPage(supplyCardQueryBean,
						card, page);
				for (CollectCardDetailDto item : results) {
					String sb = item.toDownloadString(downloadCardPwd, platConfig.getDesKey());
					bw.write(sb);
				}
				page.setPage(page.getPage() + 1);
				bw.flush();
			}
			out = response.getOutputStream();
			String[] fileList = { file.getPath() };
			ZipUtil.zip(fileList, zipName + ".zip", false, "");
			long fileLength = zipFile.length();
			response.setContentType("application/zip");
			response.setHeader("Content-Length", String.valueOf(fileLength));
			response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".zip");
			byte[] temp = FileUtils.readFileToByteArray(zipFile);
			IOUtils.write(temp, out);
			out.flush();
		} catch (Exception e) {
			log.warn("导出收卡明细列表出错", e);
		} finally {
			IOUtils.closeQuietly(bw);
			IOUtils.closeQuietly(out);
			file.delete();
			zipFile.delete();
		}
	}

	/**
	 * 停止/开启电信预判异常直接走试充
	 *
	 * @param status 1:直接走试充 0:异常n次走试充
	 * @return
	 */
	@Override
	public MessageBean changeTelecomJudge(Integer status) {
		if (Constants.STATE_OPEN.intValue() == status) {
			SimpleCacheUtil.setObject(SupRedisKey.CYCLE_TELECOM_JUDGE_FACE.toString(),
					SupRedisKey.CYCLE_TELECOM_JUDGE_FACE.toString());
		} else {
			SimpleCacheUtil.removeObject(SupRedisKey.CYCLE_TELECOM_JUDGE_FACE.toString());
		}
		return MessageBean.success();
	}

	/**
	 * 查询电信预判异常直接走试充 true 直接走试充
	 *
	 * @return
	 */
	@Override
	public boolean getTelecomJudge() {
		Object autoAudit = SimpleCacheUtil.getObject(SupRedisKey.CYCLE_TELECOM_JUDGE_FACE.toString());
		if (Objects.isNull(autoAudit)) {
			return false;
		}
		return true;
	}

	/**
	 * 三网订单异步
	 *
	 * @param orderId 会员id
	 * @return
	 */
	@Override
	public MessageBean orderAsyn(String orderId) {
		// 获取回调地址
		SupUser supUser = collectCardDetailDao.queryCardCallBackAddress(orderId);
		// 新api接口
		if (Consts.CLOSE.equals(supUser.getApiType()) && StringUtils.isBlank(supUser.getNotifyUrl())) {
			return MessageBean.fail("新api接口回调地址为空");
		}
		// 老api接口
		if (Consts.OPEN.equals(supUser.getApiType()) && StringUtils.isBlank(supUser.getCallBackUrl())) {
			return MessageBean.fail("老api接口回调地址为空");
		}
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("orderIds", StringUtils.removeEnd(orderId, ",")));
		StringBuffer url = new StringBuffer(PlatConfigUtil.getProperty("plat-url.properties", "SUPMemberSys"));
		url.append("supply/apiCardSupplyCallBack");
		String result = Httpclient.post(url.toString(), params, "utf-8", 3000, 3000);
		log.info("sup收卡管理平台请求SUP会员系统添加到API提卡回调队列url[{}]请求串:[{}]返回:[{}]", url, orderId, result);
		// 请求超时
		if (StringUtils.isBlank(result) || StringUtils.equalsIgnoreCase("读取超时", result)) {
			log.warn("sup收卡管理平台请求SUP会员系统请求超时url[{}]请求串:[{}]", url, orderId);
			return MessageBean.fail("会员异步订单提交失败");
		}
		if (StringUtils.isBlank(result) || StringUtils.equalsIgnoreCase("请求异常", result)) {
			log.warn("sup收卡管理平台请求SUP会员系统请求超时url[{}]请求串:[{}]", url, orderId);
			return MessageBean.fail("会员异步订单提交失败");
		}
		ObjectMapper mapper = new ObjectMapper();
		try {
			JsonNode jsonNode = mapper.readTree(result);
			if (Objects.isNull(jsonNode)) {
				return MessageBean.fail("会员异步订单提交失败");
			}
			if (jsonNode.get("status") != null && 0 != jsonNode.get("status").asInt()) {
				return MessageBean.fail("会员异步订单提交失败");
			}
		} catch (IOException e) {
			log.warn("json解析异常[{}]", result);
			return MessageBean.fail("会员异步订单提交失败");
		}
		return MessageBean.success();
	}

	/**
	 * 权益订单置失败
	 *
	 * @param ids    订单id
	 * @param remark 备注
	 * @return
	 */
	@Override
	public MessageBean equitySetFail(Long[] ids, String remark) {
		AtomicInteger count = new AtomicInteger(0);
		// 更新权益信用分
		for (Long id : ids) {
			SupplyCard supplyCard = collectCardDetailDao.querySupplyOrderById(id);
			int status = supplyCard.getStatus();
			if (status != 3 && status != 10 && status != 9 && status != 0) {
				continue;
			}
			int result = collectCardDetailDao.equitySetFail(id, remark, status);
			if (result > 0) {
				count.incrementAndGet();
			}
			if (EQUITY_CODE_MAP.get(remark) != null) {
				collectCardDetailDao.modifySupUserEquityCredit(supplyCard.getUserId(), EQUITY_CODE_MAP.get(remark));
			}
		}
		return MessageBean.success("操作成功" + count.get() + "条");
	}

	/**
	 * 权益订单成功置失败
	 *
	 * @param idsStr 订单id
	 * @param remark 备注
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public MessageBean equitySuccessToFail(String[] idsStr, String remark) {
		int count = 0;
		for (String id : idsStr) {
			SupplyCard supplyCard = collectCardDetailDao.querySupplyOrderById(Long.valueOf(String.valueOf(id)));
			int result = collectCardDetailDao.equitySuccessToFail(Long.valueOf(String.valueOf(id)), remark);
			if (result > 0) {
				SupplyConsumption supplyConsumption = new SupplyConsumption(supplyCard.getUserId(),
						UserAddMoneyTypeEnum.fixWithhold.getSupBalanceCgStatus(), supplyCard.getOrderId(),
						UserAddMoneyTypeEnum.fixWithhold.getMsg(),
						supplyCard.getUserPrice().multiply(BigDecimal.valueOf(-1)), 0);
				supplyFinanceService.modifyBalanceConsumption(supplyConsumption);
				BigDecimal equityCredit = BigDecimal.ZERO;
				if (EQUITY_CODE_MAP.get(remark) != null) {
					equityCredit = EQUITY_CODE_MAP.get(remark);
				}
				// 成功置失败多扣一分
				collectCardDetailDao.modifySupUserEquityCredit(supplyCard.getUserId(),
						equityCredit.subtract(BigDecimal.ONE));
				count += 1;
			}
		}
		return MessageBean.success("操作成功" + count + "条");
	}

	/**
	 * 权益订单置成功
	 *
	 * @param ids 订单id
	 * @return
	 */
	@Override
	public MessageBean equitySetSuccess(String[] ids) {
		int count = 0;
		for (String id : ids) {
			SupplyCard supplyCard = collectCardDetailDao.querySupplyOrderById(Long.valueOf(String.valueOf(id)));
			int result = collectCardDetailDao.equitySetSuccess(Long.valueOf(String.valueOf(id)));
			if (result > 0) {
				SupplyConsumption supplyConsumption = new SupplyConsumption(supplyCard.getUserId(),
						SupplyConsumption.SETTLE_TYPE, supplyCard.getOrderId(), null, supplyCard.getUserPrice(), 0);
				supplyFinanceService.modifyBalanceConsumption(supplyConsumption);
				collectCardDetailDao.modifySupUserEquityCredit(supplyCard.getUserId(), BigDecimal.ONE);
				count += 1;
			}
		}
		return MessageBean.success("操作成功" + count + "条");
	}

	/**
	 * 提交到易销卡
	 *
	 * @param orderIds 订单号
	 * @return
	 */
	private int submitCard(List<String> orderIds) {
		List<NameValuePair> params = new ArrayList<>();
		params.add(new BasicNameValuePair("orderIds", StringUtils.join(orderIds, ",")));
		StringBuffer url = new StringBuffer(PlatConfigUtil.getProperty("plat-url.properties", "SUPMemberSys"));
		url.append("supply/submitCard");
		String result = Httpclient.post(url.toString(), params, "utf-8", 3000, 3000);
		log.info("sup收卡管理平台请求SUP会员系统添加到易销卡提交队列url[{}]请求串:[{}]返回:[{}]", url, orderIds, result);

		// 请求超时
		if (StringUtils.isBlank(result) || StringUtils.equalsIgnoreCase("读取超时", result)) {
			log.warn("sup收卡管理平台请求SUP会员系统请求超时url[{}]请求串:[{}]", url, orderIds);
			return 0;
		}
		if (StringUtils.isBlank(result) || StringUtils.equalsIgnoreCase("请求异常", result)) {
			log.warn("sup收卡管理平台请求SUP会员系统请求超时url[{}]请求串:[{}]", url, orderIds);
			return 0;
		}
		ObjectMapper mapper = new ObjectMapper();
		try {
			JsonNode jsonNode = mapper.readTree(result);
			if (Objects.isNull(jsonNode)) {
				return 0;
			}
			if (jsonNode.get("status") != null && 0 != jsonNode.get("status").asInt()) {
				return 0;
			}
		} catch (IOException e) {
			log.warn("json解析异常[{}]", result);
			return 0;
		}
		return orderIds.size();
	}

	/**
	 * 设置备注
	 *
	 * @param id
	 * @param remark
	 * @param remarkType
	 * @return
	 * @throws Exception
	 */
	@Override
	public MessageBean setRemark(Long id, String remark, String remarkType) throws Exception {
		String userRemark = "userRemark";
		int updateRemark = 0;
		if (userRemark.equals(remarkType)) {
			updateRemark = collectCardDetailDao.updateRemark(id, remark);
		} else {
			Admin adminUser = adminService.getCurrentAdmin();
			remark = adminUser.getName() + ":" + remark;
			updateRemark = collectCardDetailDao.updateAdminRemark(id, remark);
		}
		if (updateRemark < 1) {
			throw new SupException(ErrorCode.SYSTEM_ERROR, "更新失败");
		}
		return MessageBean.success();
	}

	/**
	 * 权益手动补结算
	 *
	 * @param manualClearing
	 * @return
	 */
	@Override
	public MessageBean manualClearing(ManualClearing manualClearing) {
		SupplyCard supplyCard = collectCardDetailDao.getSupplyCardOrderById(manualClearing.getId());
		if (Objects.isNull(supplyCard)) {
			return MessageBean.fail("订单不存在!");
		}
		if (Objects.nonNull(supplyCard.getTransferMark())) {
			return MessageBean.fail("此订单已结算，请勿重复操作转账！");
		}
		if (supplyCard.getProductType() <= Operator.CNPC.getType()) {
			return MessageBean.fail("仅允许操作权益订单!");
		}
		if (!SupplyCardStatus.fail.getStatus().equals(supplyCard.getStatus())
				&& !SupplyCardStatus.success.getStatus().equals(supplyCard.getStatus())) {
			return MessageBean.fail("仅允许操作状态为[已售]或[停售]订单!");
		}
		ManualClearing manualClearingData = collectCardDetailDao.getManualClearing(supplyCard.getOrderId());
		if (Objects.isNull(manualClearingData)) {
			int num = collectCardDetailDao
					.insertManualClearing(new ManualClearing(supplyCard, manualClearing.getAddUserPrice()));
			log.info("手动补结算：[{}][{}][{}]", supplyCard, manualClearing, num);
		}
		return domesticConsumerHandle(supplyCard, manualClearing);
	}

	/**
	 * 权益批次再次提交
	 *
	 * @param ids
	 * @param productType
	 * @return
	 */
	@Override
	public MessageBean equityBatchResubmission(String[] ids, Integer productType) {
		try {
			Admin adminUser = adminService.getCurrentAdmin();
			AtomicInteger count = new AtomicInteger(0);
			String idStr = StringUtils.join(ids, ",");
			List<SupplyCard> equityCardOrderList = collectCardDetailDao.equityBatchOrderList(idStr);
			equityCardOrderList.forEach(equityCardOrder -> {
				if (!SupplyCardStatus.preSell.getStatus().equals(equityCardOrder.getStatus())
						&& !SupplyCardStatus.selling.getStatus().equals(equityCardOrder.getStatus())) {
					return;
				}
				int num = collectCardDetailDao.queryResubmissionMark(equityCardOrder.getOrderId());
				if (num > 0) {
					return;
				}
				int resubmissionMark = collectCardDetailDao.updateBatchResubmissionMark(equityCardOrder.getOrderId(),
						adminUser.getName() + "再次提交", SupplyCardStatus.preSell.getStatus(),
						equityCardOrder.getStatus());
				if (resubmissionMark > 0) {
					count.incrementAndGet();
				}
			});
			return MessageBean.success("成功操作" + count.get() + "条记录");
		} catch (Exception e) {
			log.warn("[权益批次再次提交]异常[{}][{}]{}", productType, ids, e, e);
			return MessageBean.fail("提交失败");
		}
	}

	/**
	 * 普通用户订单处理
	 *
	 * @param supplyCard
	 * @param manualClearing
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class)
	public MessageBean domesticConsumerHandle(SupplyCard supplyCard, ManualClearing manualClearing) {
		try {
			if (!Integer.valueOf(0).equals(manualClearing.getApplyType())) {
				return MessageBean.fail("仅允许【部分加款】操作非闲鱼用户订单");
			}
			SupplyBalance balance = supplyFinanceService.querySupplyBalanceVersion(supplyCard.getUserId());
			int row = supplyFinanceDao.modifyBalance(balance, manualClearing.getAddUserPrice().doubleValue(),
					SupplyConsumption.SETTLE_TYPE);
			if (row != 1) {
				log.warn("[手动补结算，余额修改失败][{}] [{}]", supplyCard.getOrderId(), row);
				throw new OperateFailException(supplyCard.getOrderId() + ",修改手动补结算余额失败");
			}
			Admin admin = adminService.getCurrentAdmin();
			int num = collectCardDetailDao.updateTransferMarkByManualClearing(supplyCard.getOrderId(), admin.getName()
					+ "手动补结算:" + manualClearing.getAddUserPrice() + "元,原因:" + manualClearing.getRemark());
			if (num != 1) {
				log.warn("转账标记失败[{}][{}]", supplyCard.getOrderId(), num);
				throw new OperateFailException(supplyCard.getOrderId() + ",普通用户标记手动补结算余额失败");
			}
			SupplyConsumption supplyConsumption = new SupplyConsumption(supplyCard.getUserId(), SupplyConsumption.ADDED,
					supplyCard.getOrderId(), null, manualClearing.getAddUserPrice(), 0);
			supplyConsumption.setBalance(balance.getBalance().add(supplyConsumption.getMoney()));
			supplyConsumption.setType(0);
			supplyConsumption.setChannel("补结算");
			row = supplyFinanceDao.createSupplyConsumption(supplyConsumption);
			if (row != 1) {
				throw new OperateFailException("{" + supplyCard.getOrderId() + "}手动补结算新增消费明细异常");
			}
		} catch (Exception e) {
			log.warn("[转账异常][{}]{}", supplyCard.getOrderId(), e, e);
			throw new OperateFailException(supplyCard.getOrderId() + ",转账异常");
		}
		return MessageBean.success();
	}

}
